Step Functions의 Error Handing를 해봤습니다.
안녕하세요, 임채정입니다.
이번 블로그에서는 Step Functions의 Error Handing에 대해 알아보고 테스트해보겠습니다.
Step Functions이 뭔지 알고 싶으신 분은 아래 블로그를 참고하세요.
아젠다
- Error Handing 이란
- 실제로 해보기
- 마무리
1. Error Handing 이란
- 오류를 처리하는 기능
- 오류의 여러가지 발생 원인
- 스테이트 머신의 정의 문제
- Choice 상태에 일치하는 룰이 없는 경우
- 작업 실패
- Lambda 함수의 예외
- 일시적인 문제
- 네트워크 파티션 이벤트
- 스테이트 머신의 정의 문제
- 기본적으로는 상태에서 오류가 보고되면 AWS Step Functions 실행 전체가 실패
오류의 종류
States.ALL
- 정의되어진 오류 이름과 일치하는 모든 오류에 해당하는 경우
States.DataLimitExceeded
- 커넥터의 출력이 페이로드 크기 할당량보다 큰 경우
- 상태 출력이 페이로드 크기 할당량보다 큰 경우
- Parameters 처리 후 상태 입력이 페이로드 크기 할당량보다 큰 경우
States.Runtime
- 처리할 수 없는 일부 예외로 인해 실행이 실패한 경우
States.HeartbeatTimeout
HeartbeatSeconds
값보다 장시간 실행되어 하트비트 전송에 실패한 경우
States.Timeout
TimeoutSeconds
값보다 장시간 실행되었거나HeartbeatSeconds
값보다 긴 간격 하트 비트 송신에 실패 경우
States.TaskFailed
- 실행 중 실패한 경우
States.Timeout
이외의 모든 기존의 에러명에 일치하는 경우에도 사용 가능
States.Permissions
- 지정된 코드를 실행하기에 충분한 권한이 없는 경우
커스텀 오류
- 사용자가 만드는 오류
2. 실제로 해보기
이번에는 실제로 Error Handing을 어떤 식으로 하면 되는지 해보도록 하겠습니다.
먼저 이번에 해볼 워크플로입니다.
그럼 실제로 람다 함수와 Step Functions의 상태 머신을 작성해보겠습니다.
람다 함수
먼저 InvokeFunction
단계에 들어갈 에러를 발생시킬 람다 함수를 작성하겠습니다.
함수 생성에서 블루프린트 사용을 선택하고 step-functions
을 검색해서 step-functions-error
을 선택하고 구성을 눌러줍니다.
구성에서는 이름 등을 입력할 수 있습니다.
또한, Step Functions 의 커스텀 error 에 대한 출력을 하는 기본적인 코드가 작성되어 있는데 이 코드는 수정하지 않은 채로 함수를 생성해주겠습니다.
함수가 생성되면 위에서 확인했던 코드 소스를 볼 수 있습니다.
테스트를 해보면 에러 결과가 제대로 출력되는 것을 확인할 수 있습니다.
Test Event Name FunctionTest Response { "errorType": "CustomError", "errorMessage": "This is a custom error!", "trace": [ "Error", " at Runtime.exports.handler (/var/task/index.js:6:29)", " at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)" ] } Function Logs START RequestId: 0cfdb0ac-a5d7-4030-bc3b-44b5afc5e0d0 Version: $LATEST 2022-02-24T06:03:46.155Z 0cfdb0ac-a5d7-4030-bc3b-44b5afc5e0d0 ERROR Invoke Error {"errorType":"CustomError","errorMessage":"This is a custom error!","name":"CustomError","message":"This is a custom error!","stack":["Error"," at Runtime.exports.handler (/var/task/index.js:6:29)"," at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"]} END RequestId: 0cfdb0ac-a5d7-4030-bc3b-44b5afc5e0d0 REPORT RequestId: 0cfdb0ac-a5d7-4030-bc3b-44b5afc5e0d0 Duration: 29.65 ms Billed Duration: 30 ms Memory Size: 128 MB Max Memory Used: 55 MB Init Duration: 161.39 ms Request ID 0cfdb0ac-a5d7-4030-bc3b-44b5afc5e0d0
이것으로 커스텀 에러를 발생시키는 함수 작성이 끝났습니다.
상태 머신 작성
이번에는 Step Functions 의 상태 머신을 작성해보겠습니다.
코드로 워크플로 작성
을 선택해주고 표준
을 선택해줍니다.
정의
부분에서 아래 코드를 붙여 줍니다.
아래 코드에서는 Retry
필드에서 ErrorEquals 의 값과 같은 오류가 발생할 경우 설정한 값은 다음과 같습니다.
IntervalSeconds
필드에서 첫 번째 재시도 전에 기다리는 시간 (초) 설정MaxAttempts
필드로 최대 재시도 횟수 설정BackoffRate
필드로 재시도 때마다 재시도 간격이 늘어나도록 곱하는 수를 설정했습니다.
또한, Catch
필드에서 오류를 처리하고 있습니다.
즉, CustomError
가 발생할 경우 2번을 재시도 하고 첫 번째 재시도 전에 1초를 기다리고 그 후에는 2배를 곱한 수로 재시도를 실행한다는 뜻입니다.
{ "Comment": "A Retry and Catch example", "StartAt": "InvokeFunction", "States": { "InvokeFunction": { "Type": "Task", "Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:FUNCTION_NAME", "Retry": [ { "ErrorEquals": [ "CustomError" ], "IntervalSeconds": 1, "MaxAttempts": 2, "BackoffRate": 2 }, { "ErrorEquals": [ "States.TaskFailed" ], "IntervalSeconds": 10, "MaxAttempts": 2, "BackoffRate": 2 }, { "ErrorEquals": [ "States.ALL" ], "IntervalSeconds": 5, "MaxAttempts": 5, "BackoffRate": 2 } ], "Catch": [ { "ErrorEquals": [ "CustomError" ], "Next": "CustomErrorFallback" }, { "ErrorEquals": [ "States.TaskFailed" ], "Next": "TaskFailedFallback" }, { "ErrorEquals": [ "States.ALL" ], "Next": "AllErrorFallback" } ], "End": true }, "CustomErrorFallback": { "Type": "Pass", "Result": "custom lambda function exception", "End": true }, "TaskFailedFallback": { "Type": "Pass", "Result": "TaskFailed error code", "End": true }, "AllErrorFallback": { "Type": "Pass", "Result": "ALL error code", "End": true } } }
Resource
에는 아까 위에서 작성한 람다 함수의 ARN을 붙여 줍니다.
그러면 코드에 따른 워크플로를 시각적으로도 확인할 수 있습니다.
이걸로 상태 머신의 작성이 끝났습니다.
결과 테스트
그럼 작성한 상태 머신을 실제로 실행시켜서 동작을 확인해보겠습니다.
별다른 설정없이 실행을 시작합니다.
다음과 같은 결과가 나왔습니다.
실행 이벤트 내역을 통해 좀 더 자세히 살펴보겠습니다.
1) InvokeFunction
단계에서 실행된 람다 함수는 CustomError
가 발생하는 함수이기 때문에 CustomError
가 발생했습니다.
2) 람다 함수는 총 3번의 실행을 했습니다. (2번은 재실행: "MaxAttempts": 2
)
3) 재시도 후에도 CustomError
가 발생했기 때문에 output
으로 CustomError
를 출력했습니다.
4) 그 후 CustomErrorFallback
단계에서 End
에 도달
그럼 이번에는 CustomError
가 아니라 TaskFailed
에러를 발생시켜보겠습니다.
람다 함수를 수정해서 input
으로 들어가는 에러의 이름을 다른 것으로 수정합니다.
그 후 실행을 시작합니다.
이번 실행 결과입니다. 이번에는 TaskFailedFallback
단계를 통해 End
에 도달했습니다.
실행 이벤트 내역을 통해 살펴보면
1) InvokeFunction
단계에서 실행된 람다 함수에서 OtherError
에러 발생
2) 람다 함수는 총 3번의 실행을 했습니다. (2번은 재실행: "MaxAttempts": 2
)
3) 재시도 후에도 OtherError
에러가 계속 발생했기 때문에 output
으로 OtherError
를 출력했습니다.
4) TaskFailed
에러는 States.Timeout
이외의 모든 에러명이 일치하는 에러명이 없을 때 발생하기 때문에 TaskFailedFallback
단계로 넘어가서 End
에 도달
3. 마무리
이번 블로그에서는 Step Functions 서비스의 상태 머신에서 에러 처리를 하는 법에 대해서 알아보고 정리해봤습니다.
Retry
나 Catch
의 다양한 필드를 통해 커스텀 에러와 정의되어진 기존 에러의 처리방법을 정의할 수 있어서 좋은 기능이라고 생각합니다.